SPB Git forge

spb/toveli

Public
14commits 1branches 0releases
1.1 MBsize
maindefault branch
5 h agolast push
TypeScript 50.6% JavaScript 46.1% SQL 2.1% Shell 0.6% CSS 0.5%
2.4 KB · 24 lines typescript
Raw Blame History
1import { NextRequest, NextResponse } from "next/server";2import { assertSameOrigin, currentUser, requireUser } from "@/lib/auth/session";3import { getListingFull, updateListing, deleteDraft, ConflictError, assertOwner } from "@/lib/listings/service";4import { ListingInput, publishProblems } from "@/lib/listings/types";5import { mediaUrl } from "@/lib/listings/media";6import { apiError, handle, parseBody } from "@/lib/api";7export const dynamic = "force-dynamic";8type P = { params: Promise<{ id: string }> };9export async function GET(_req: NextRequest, { params }: P) {10  try {11    const { id } = await params; const l = await getListingFull(id); if (!l) return apiError(404, "not_found", "Annonce introuvable");12    const u = await currentUser(); const isOwner = !!u && (l.ownerUserId === u.id || u.roles.includes("ADMIN") || u.roles.includes("MODERATOR"));13    if (l.status !== "PUBLISHED" && !isOwner) return apiError(404, "not_found", "Annonce introuvable");14    const media = l.media.map((m) => ({ id: m.id, url: mediaUrl(m.storageKey, 800), large: mediaUrl(m.storageKey, 1600), thumb: mediaUrl(m.storageKey, 320), position: m.position, altText: m.altText, width: m.width, height: m.height }));15    const problems = isOwner ? publishProblems({ listingType: l.listingType, propertyType: l.property.propertyType, priceAmount: l.priceAmount, title: l.title, description: l.description, city: l.property.city, lat: l.property.lat, mediaCount: l.media.length, attestedAt: l.attestedAt, bedrooms: l.property.bedrooms, areaSqft: l.property.areaSqft }) : undefined;16    return NextResponse.json({ listing: { ...l, media, ownerUserId: isOwner ? l.ownerUserId : undefined, problems } });17  } catch (e) { return handle(e); }18}19export async function PATCH(req: NextRequest, { params }: P) {20  try { await assertSameOrigin(); const u = await requireUser(); const { id } = await params; const input = await parseBody(req, ListingInput); const l = await updateListing(id, u.id, u.roles, input); return NextResponse.json({ listing: l }); }21  catch (e) { if (e instanceof ConflictError) return apiError(409, "conflict", e.message); return handle(e); }22}23export async function DELETE(_req: NextRequest, { params }: P) { try { await assertSameOrigin(); const u = await requireUser(); const { id } = await params; const l = await getListingFull(id); if (l) assertOwner(l, u.id, u.roles); await deleteDraft(id, u.id, u.roles); return NextResponse.json({ ok: true }); } catch (e) { return handle(e); } }24